﻿using Core.DomainServices;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Validation;
using DocumentFormat.OpenXml.Wordprocessing;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Insfrastructure.DomainServices
{
    public class ExportToWord : IDocumentService
    {
        private readonly IAppConfig appConfig;
        private readonly IWebClientService clientService;

        public ExportToWord(IAppConfig appConfig, IWebClientService clientService)
        {
            this.appConfig = appConfig;
            this.clientService = clientService;
        }

        public string Export(string html, string fileName)
        {
            string generatedDocument = appConfig.OutputFolder + Path.DirectorySeparatorChar + fileName;

            using (WordprocessingDocument package = WordprocessingDocument.Create(generatedDocument, WordprocessingDocumentType.Document))
            {
                string altChunkId = "AltChunkId" + (DateTime.Now.Minute + DateTime.Now.Second + DateTime.Now.Millisecond); 

                MainDocumentPart mainDocPart = package.MainDocumentPart;
                if (mainDocPart == null)
                {
                    mainDocPart = package.AddMainDocumentPart();
                }
                if (mainDocPart.Document == null)
                {
                    mainDocPart.Document = new Document();
                }
                if (mainDocPart.Document.Body == null)
                {
                    mainDocPart.Document.AppendChild(new Body());
                    mainDocPart.Document.Body.AppendChild(new Paragraph());
                }
                AlternativeFormatImportPart chunk = mainDocPart.AddAlternativeFormatImportPart(
                      AlternativeFormatImportPartType.Html, altChunkId);

                using (MemoryStream ms = new MemoryStream(UTF8Encoding.Default.GetBytes(html)))
                {
                    chunk.FeedData(ms);
                }

                AltChunk altChunk = new AltChunk();
                altChunk.Id = altChunkId;

                // Embed AltChunk after the last paragraph.
                mainDocPart.Document.Body.InsertAfter(
                    altChunk, mainDocPart.Document.Body.Elements<Paragraph>().Last());

                package.MainDocumentPart.Document.Save();
                
                AssertThatOpenXmlDocumentIsValid(package);
           
            }

            return generatedDocument;
        }
        void AssertThatOpenXmlDocumentIsValid(WordprocessingDocument wpDoc)
        {
            var validator = new OpenXmlValidator(FileFormatVersions.Office2010);
            var errors = validator.Validate(wpDoc);

            if (!errors.GetEnumerator().MoveNext())
                return;

            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("The document doesn't look 100% compatible with Office 2010.\n");

            Console.ForegroundColor = ConsoleColor.Gray;
            foreach (ValidationErrorInfo error in errors)
            {
                Console.Write("{0}\n\t{1}", error.Path.XPath, error.Description);
                Console.WriteLine();
            }

            Console.ReadLine();
        }


        public IList<string> Export(IList<string> urls)
        {
            if (urls == null || !urls.Any()) return null;

            IList<string> results = new List<string>();

            foreach(var url in urls)
            {
                var html = clientService.GetDataFromUrl(url);
                var appConfig = new AppConfig();

                string fileName = appConfig.GetHost(url) + ".docx";
                Export(html, fileName);
                results.Add(fileName);
            }

            return results;
        }
    }
}
